@@ -8,7 +8,7 @@ module Agents |
||
| 8 | 8 |
|
| 9 | 9 |
description <<-MD |
| 10 | 10 |
The SentimentAgent generates `good-bad` (psychological valence or happiness index), `active-passive` (arousal), |
| 11 |
- and `strong-weak` (dominance) score. It will output a value between 1 and 9. |
|
| 11 |
+ and `strong-weak` (dominance) score. It will output a value between 1 and 9. It will only work on English content. |
|
| 12 | 12 |
|
| 13 | 13 |
Make sure the content this agent is analyzing have sufficient length to get respectable results. |
| 14 | 14 |
|
@@ -0,0 +1,74 @@ |
||
| 1 |
+module Agents |
|
| 2 |
+ class TranslationAgent < Agent |
|
| 3 |
+ |
|
| 4 |
+ cannot_be_scheduled! |
|
| 5 |
+ |
|
| 6 |
+ description <<-MD |
|
| 7 |
+ You can use Translation Agent to translate text between natural languages. |
|
| 8 |
+ Services are provided using Microsoft Translator. You can [sign up](https://datamarket.azure.com/dataset/bing/microsofttranslator) and [register your application](https://datamarket.azure.com/developer/applications/register) to get `client_id` and `client_secret` which are required to use this agent. |
|
| 9 |
+ `to` must be filled with a [translator language code](http://msdn.microsoft.com/en-us/library/hh456380.aspx). |
|
| 10 |
+ |
|
| 11 |
+ Specify what you would like to translate in `content` field, by specifying key and JSONPath of content to be translated. |
|
| 12 |
+ |
|
| 13 |
+ `expected_receive_period_in_days` is the maximum number of days you would allow to pass between events. |
|
| 14 |
+ MD |
|
| 15 |
+ |
|
| 16 |
+ event_description <<-MD |
|
| 17 |
+ User defined |
|
| 18 |
+ MD |
|
| 19 |
+ |
|
| 20 |
+ def default_options |
|
| 21 |
+ {
|
|
| 22 |
+ :client_id => "xxxxxx", |
|
| 23 |
+ :client_secret => "xxxxxx" , |
|
| 24 |
+ :to => "fi", |
|
| 25 |
+ :expected_receive_period_in_days => 1, |
|
| 26 |
+ :content => {
|
|
| 27 |
+ :text => "$.message.text", |
|
| 28 |
+ :content => "$.xyz" |
|
| 29 |
+ } |
|
| 30 |
+ } |
|
| 31 |
+ end |
|
| 32 |
+ |
|
| 33 |
+ def working? |
|
| 34 |
+ last_receive_at && last_receive_at > options[:expected_receive_period_in_days].to_i.days.ago |
|
| 35 |
+ end |
|
| 36 |
+ |
|
| 37 |
+ def translate(text,to,access_token) |
|
| 38 |
+ translate_uri = URI "http://api.microsofttranslator.com/v2/Ajax.svc/Translate" |
|
| 39 |
+ params = {
|
|
| 40 |
+ :text => text, |
|
| 41 |
+ :to => to |
|
| 42 |
+ } |
|
| 43 |
+ translate_uri.query = URI.encode_www_form params |
|
| 44 |
+ request = Net::HTTP::Get.new translate_uri |
|
| 45 |
+ request['Authorization'] = "Bearer" + " " + access_token |
|
| 46 |
+ http = Net::HTTP.new translate_uri.hostname, translate_uri.port |
|
| 47 |
+ response = http.request request |
|
| 48 |
+ YAML.load response.body |
|
| 49 |
+ end |
|
| 50 |
+ |
|
| 51 |
+ def validate_options |
|
| 52 |
+ unless options[:client_id].present? && options[:client_secret].present? && options[:to].present? && options[:content].present? && options[:expected_receive_period_in_days].present? |
|
| 53 |
+ errors.add :base, "client_id,client_secret,to,expected_receive_period_in_days and content are all required" |
|
| 54 |
+ end |
|
| 55 |
+ end |
|
| 56 |
+ |
|
| 57 |
+ def receive(incoming_events) |
|
| 58 |
+ auth_uri = URI "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13" |
|
| 59 |
+ response = Net::HTTP.post_form auth_uri, :client_id => options[:client_id], |
|
| 60 |
+ :client_secret => options[:client_secret], |
|
| 61 |
+ :scope => "http://api.microsofttranslator.com", |
|
| 62 |
+ :grant_type => "client_credentials" |
|
| 63 |
+ access_token = JSON.parse(response.body)["access_token"] |
|
| 64 |
+ incoming_events.each do |event| |
|
| 65 |
+ translated_event = {}
|
|
| 66 |
+ options[:content].each_pair do |key,value| |
|
| 67 |
+ translate_value = Utils.values_at event.payload, value |
|
| 68 |
+ translated_event[key] = translate translate_value.first, options[:to], access_token |
|
| 69 |
+ end |
|
| 70 |
+ create_event :payload => translated_event |
|
| 71 |
+ end |
|
| 72 |
+ end |
|
| 73 |
+ end |
|
| 74 |
+end |
@@ -7,7 +7,7 @@ module Agents |
||
| 7 | 7 |
description <<-MD |
| 8 | 8 |
The TwilioAgent receives and collects events and sends them via text message when scheduled. |
| 9 | 9 |
|
| 10 |
- It is assumed that events have a `:message`, `:text`, or `:sms` key, the value of which is sent as the content of the text message. |
|
| 10 |
+ It is assumed that events have a `:message`, `:text`, or `:sms` key, the value of which is sent as the content of the text message. You can use Event Formatting Agent if your event does not provide these keys. |
|
| 11 | 11 |
|
| 12 | 12 |
Set `receiver_cell` to the number to receive text messages and `sender_cell` to the number sending them. |
| 13 | 13 |
|
@@ -0,0 +1,92 @@ |
||
| 1 |
+require 'spec_helper' |
|
| 2 |
+ |
|
| 3 |
+describe Agents::TranslationAgent do |
|
| 4 |
+ before do |
|
| 5 |
+ @valid_params = {
|
|
| 6 |
+ :name => "somename", |
|
| 7 |
+ :options => {
|
|
| 8 |
+ :client_id => "xxxxxx", |
|
| 9 |
+ :client_secret => "xxxxxx" , |
|
| 10 |
+ :to => "fi", |
|
| 11 |
+ :expected_receive_period_in_days => 1, |
|
| 12 |
+ :content => {
|
|
| 13 |
+ :text => "$.message", |
|
| 14 |
+ :content => "$.xyz" |
|
| 15 |
+ } |
|
| 16 |
+ } |
|
| 17 |
+ } |
|
| 18 |
+ |
|
| 19 |
+ @checker = Agents::TranslationAgent.new(@valid_params) |
|
| 20 |
+ @checker.user = users(:jane) |
|
| 21 |
+ @checker.save! |
|
| 22 |
+ |
|
| 23 |
+ @event = Event.new |
|
| 24 |
+ @event.agent = agents(:jane_weather_agent) |
|
| 25 |
+ @event.payload = {
|
|
| 26 |
+ :message => "somevalue", |
|
| 27 |
+ :xyz => "someothervalue" |
|
| 28 |
+ } |
|
| 29 |
+ |
|
| 30 |
+ stub_request(:any, /microsoft/).to_return(:body => "response", :status => 200) |
|
| 31 |
+ stub_request(:any, /windows/).to_return(:body => JSON.dump({
|
|
| 32 |
+ :access_token => 'xxx'}), :status => 200) |
|
| 33 |
+ |
|
| 34 |
+ end |
|
| 35 |
+ |
|
| 36 |
+ describe "#receive" do |
|
| 37 |
+ it "checks if it can handle multiple events" do |
|
| 38 |
+ event1 = Event.new |
|
| 39 |
+ event1.agent = agents(:bob_weather_agent) |
|
| 40 |
+ event1.payload = {
|
|
| 41 |
+ :xyz => "value1", |
|
| 42 |
+ :message => "value2" |
|
| 43 |
+ } |
|
| 44 |
+ |
|
| 45 |
+ lambda {
|
|
| 46 |
+ @checker.receive([@event,event1]) |
|
| 47 |
+ }.should change { Event.count }.by(2)
|
|
| 48 |
+ end |
|
| 49 |
+ end |
|
| 50 |
+ |
|
| 51 |
+ describe "#working?" do |
|
| 52 |
+ it "checks if events have been received within expected receive period" do |
|
| 53 |
+ @checker.should_not be_working |
|
| 54 |
+ Agents::TranslationAgent.async_receive @checker.id, [@event.id] |
|
| 55 |
+ @checker.reload.should be_working |
|
| 56 |
+ two_days_from_now = 2.days.from_now |
|
| 57 |
+ stub(Time).now { two_days_from_now }
|
|
| 58 |
+ @checker.reload.should_not be_working |
|
| 59 |
+ end |
|
| 60 |
+ end |
|
| 61 |
+ |
|
| 62 |
+ describe "validation" do |
|
| 63 |
+ before do |
|
| 64 |
+ @checker.should be_valid |
|
| 65 |
+ end |
|
| 66 |
+ |
|
| 67 |
+ it "should validate presence of content key" do |
|
| 68 |
+ @checker.options[:content] = nil |
|
| 69 |
+ @checker.should_not be_valid |
|
| 70 |
+ end |
|
| 71 |
+ |
|
| 72 |
+ it "should validate presence of expected_receive_period_in_days key" do |
|
| 73 |
+ @checker.options[:expected_receive_period_in_days] = nil |
|
| 74 |
+ @checker.should_not be_valid |
|
| 75 |
+ end |
|
| 76 |
+ |
|
| 77 |
+ it "should validate presence of client_id key" do |
|
| 78 |
+ @checker.options[:client_id] = "" |
|
| 79 |
+ @checker.should_not be_valid |
|
| 80 |
+ end |
|
| 81 |
+ |
|
| 82 |
+ it "should validate presence of client_secret key" do |
|
| 83 |
+ @checker.options[:client_secret] = "" |
|
| 84 |
+ @checker.should_not be_valid |
|
| 85 |
+ end |
|
| 86 |
+ |
|
| 87 |
+ it "should validate presence of 'to' key" do |
|
| 88 |
+ @checker.options[:to] = "" |
|
| 89 |
+ @checker.should_not be_valid |
|
| 90 |
+ end |
|
| 91 |
+ end |
|
| 92 |
+end |